﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Xml.Linq;
using Common.Constants;
using Common.Helper;

namespace MainProcessor.Processors
{
    public class BaseElementProcessor
    {
        private Dictionary<string, List<XElement>> elements;

        public bool IsEmpty
        {
            get { return elements.Count == 0; }
        }

        public BaseElementProcessor()
        {
            elements = new Dictionary<string, List<XElement>>();
        }

        protected T GetValue<T>(string key, XmlConstants constant)
        {
            return GetValue<T>(key, constant, DefaultGetValue);
        }

        private static XElement DefaultGetValue(IEnumerable<XElement> node, XmlConstants constant)
        {
            return node.First().Element(constant);
        }

        protected T GetValue<T>(string key, XmlConstants constant, Func<IEnumerable<XElement>, XmlConstants, XElement> getValue)
        {
            if (elements.ContainsKey(key))
            {
                var converter = TypeDescriptor.GetConverter(typeof(T));
                var node = elements[key];
                var value = getValue(node, constant);
                return value.IsNullOrEmpty() || converter == null ? default(T) : (T)converter.ConvertFrom(value.Value);
            }
            return default(T);
        }
        

        public virtual bool Initialise(XElement element, XmlConstants container, XmlConstants filter)
        {
            elements = (from elementItem in element.Descendants(container)
                        let type = elementItem.Element(filter)
                        where !type.IsNullOrEmpty()
                        group elementItem by type.Value
                            into elementGroup
                            select new { elementGroup.Key, Contents = elementGroup.ToList() })
                                     .ToDictionary(x => x.Key, x => x.Contents);
            return Initialise(elements);
        }

        protected virtual bool Initialise(Dictionary<string, List<XElement>> e)
        {
            return e.Count > 0;
        }
    }
}
